import debounce from 'lodash.debounce'
import { i18nRender } from '@/locales'
/**
 * 表单字段远程验证
 */
const asyncValidateMixin = {
  data () {
    return {
      canSubmit: true, // 远程验证请求过程中，表单不给提交，不然会有两个errorMessage
      validator: {},
      needVerify: {}
    }
  },

  methods: {
    $_asyncValidateMixin_init (fields) {
      this.validator = {}
      this.needVerify = {}
      for (const field of fields) {
        this.$set(this.validator, `${field.fieldName}ValidProps`, {
          validStatus: 'error',
          hasFeedback: false
        })
        this.$set(this.needVerify, field.fieldName, true)
        const validFunction = this.$_asyncValidateMixin_generator(field)
        this.$set(this.validator, `${field.fieldName}Validator`, debounce(validFunction, 150))
      }
    },

    $_asyncValidateMixin_generator (field) {
      const { fieldName, caller, extraParams } = field
      return (rule, value, callback) => {
        value = typeof (value) === 'string' ? value.trim() : value
        if (value) {
          this.canSubmit = false
          caller(
            Object.assign({ field: fieldName, value }, typeof extraParams === 'function' ? extraParams() : extraParams)
          )
            .then(res => {
              this.$set(this.validator, `${fieldName}ValidProps`, {
                validStatus: 'error',
                hasFeedback: false
              })
              const { code, message } = res
              // messageData
              if (code === 'unique_error_code') {
                this.$set(this.needVerify, fieldName, true)
                callback(i18nRender(`${message}`))
              } else {
                // 凡是主动远程校验过的字段，都不再参与最终校验
                this.$set(this.needVerify, fieldName, false)
                callback()
              }
            })
            .catch(() => {
              this.$set(this.validator, `${fieldName}ValidProps`, {
                validStatus: 'error',
                hasFeedback: false
              })
            }).finally(() => {
              this.canSubmit = true
            })
        } else {
          this.$set(this.needVerify, fieldName, true)
          this.$set(this.validator, `${fieldName}ValidProps`, {
            validStatus: 'error',
            hasFeedback: false
          })
          callback()
        }
      }
    },

    /**
     * 将不需要最终验证的字段过滤掉
     * @param { Object } values 表单字段值，包括参与校验的所有字段
     */
    $_asyncValidateMixin_fieldsFilter (values) {
      const fields = { ...values }
      for (const prop in this.needVerify) {
        if (this.needVerify.hasOwnProperty(prop) && !this.needVerify[prop]) {
          delete fields[prop]
        }
      }

      return Object.keys(fields)
    },

    /**
     * 重置所有字段的 needVerify
     */
    $_asyncValidateMixin_resetFields () {
      for (const prop in this.needVerify) {
        if (this.needVerify.hasOwnProperty(prop) && !this.needVerify[prop]) {
          this.needVerify[prop] = true
        }
      }
    }
  }
}

export default asyncValidateMixin
